<!DOCTYPE html>
<!--
 This code was created by Federico Elles which
 can be found at http://code.google.com/p/predictionwiz/
 
 Please let me know about errors and improvements via info@3x3Links.com or the link above.
-->
<html>
<head>
	<meta charset=utf-8 />
	<title>Prediction Wizard</title>
	<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/main.css" />
	<link rel="shortcut icon" href="/stylesheets/favicon.png" />
	<link type="text/css" href="/css/smoothness/jquery-ui-1.8.6.custom.css" rel="Stylesheet" />	
	<script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
	<script type="text/javascript" src="/js/jquery-ui-1.8.6.custom.min.js"></script>
	<!--[if IE]>
		<script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->		
</head>
<body>
<div class="div_menu_adm">
<a href="/adm/">Admin</a>
{% if user %}
 | <a href="/adm/exit">Sign out</a>
{% else %}
 | <a href="/signin">Sign in</a>
{% endif %}

</div>

<h1 title="Home">
<img src="/stylesheets/logo.png">
Prediction Wizard v1.6
</h1>
<div id="tabs">
	<ul>
		<li><a href="#tabs-3">Generator</a></li>
		<li><a href="#tabs-2">Validator</a></li>
		<li><a href="#tabs-1">Simulator</a></li>
		<li><a href="#tabs-5">Mass Prediction</a></li>
        <li><a href="#tabs-6">Learn</a></li>
		<li><a href="#tabs-4">About</a></li>		
		
	</ul>
	<div id="tabs-1">

<!--
  Simulator
-->
<form id="form_gen">
<table>
<p>Test a prediction model.</p>
<tr>
<td style="width:120px;">Model:</td>
<td>
  <select name="model" id="inp_model">
  {% for record in records %}
	  <option value="{{record.key }}">{{ record.caption }}</option>
  {% endfor %}
  </select>
</td>
</tr><tr> 
<td>Test data:</td>
<td>
  <input type="text" name="content" id="inp_content" value="Enter your test data string here" />
</td>  
</tr><tr> 
<td>Result data type:</td>
<td>
  <select id="datatype">
    <option value="json">JSON</option>
	<option value="html">HTML</option>
  </select>
</td> 
</tr><tr> 
<td></td>
<td><input type="submit" value="Predict"/></td>
</tr><tr> 
<td>Result:</td>
<td>
  <div id="div_result">No predictions done yet</div>
</td>
</tr><tr id="tr_correction"> 
<td>Correction:</td>
<td>
  <div id=div_quick_answer>
    One-Click-Correction&#8482;:<br>
	<div id=div_quick_buttons></div>
	<hr>
  </div>
  Correct answer:
  <select id="sel_answer">
  </select>
  <button id="btn_correct">Save</button><span id="span_correct_result"></span>
</td>
</tr>
</table>
</form>

<div id="div_result_log">
<br />
<hr>
<h3>Result Log</h3>
<table class="tbl_results">
<tr>
  <th>Test data</th>
  <th style="width:200px;">Result</th>
</tr>
<tbody id="tb_result_log">
</tbody>
</table>
</div>
{% if user %}
<hr>
<p> GET API:<br>
  /api/predict?model=<span class="span_sim_model_key"></span>&content=[query] - returns result as single string
</p>
<p>Only for public data models: <a target="_blank" id="a_demo" href="#">Demo page</a></p>

{% endif %}
<!--
  End
-->
	
	</div>
	<div id="tabs-6">

<!--
  Learn
-->
<form id="form_learn">
<table>
<p>Add data rows to a prediction model.</p>
<tr>
<td style="width:120px;">Model:</td>
<td>
  <select name="model" id="inp_model_learn">
  {% for record in records %}
	  <option value="{{record.key }}">{{ record.caption }}</option>
  {% endfor %}
  </select>
</td>
</tr><tr> 
<td>Learning data:</td>
<td>
  <textarea style="width:100%" type="text" name="content" id="inp_content_learn" >correct-answer,data1,data2,data3...</textarea>
</td>  
</tr><tr> 
<td></td>
<td><input type="submit" value="Learn"/></td>
</tr><tr> 
<td>Result:</td>
<td>
  <div id="div_result_learn">No learning done yet</div>
</td>
</tr>
</table>
</form>

<div id="div_result_log_learn">
<br />
<hr>
<h3>Learning Log</h3>
<table id="tbl_result_log_learn">
<tr>
  <th>Learning data</th>
  <th style="width:200px;">Result</th>
</tr>
<tbody id="tb_result_log_learn">
</tbody>
</table>
</div>
{% if user %}
<hr>
<p> GET API:<br>
/api/learn?model=<span class="span_sim_model_key"></span>&content=[query]&answer=[correct-answer] - adds a single data row to the prediction model. Changes might not incorporate directly.</p>
{% endif %}
<!--
  End
-->
	
	</div>	
	<div id="tabs-2">
	
<!--
  Validator
-->

<p>Validate a learning file against a prediction model</p>
<table>
<tr>
<td style="width:120px;">Model:</td>
<td>
  <select name="model" id="inp_model_val">
  {% for record in records %}
	  <option value="{{record.key }}">{{ record.caption }}</option>
  {% endfor %}
  </select>
</td>
</tr>
</table>	

	<b>Input</b><br />
	<textarea id="ta_validator"></textarea>
	<br /><button id="btn_validator">Validate</button>
		<span id="span_val_results_count"></span>
		<span id="span_val_predicted_count"></span>
		
	<div id="div_val_more_options">
		<hr>
		<b>Options</b><br/>

		<button id="btn_show_failed">Show errors</button>
		<button id="btn_show_all">Show all</button>
		| 
		<button id="btn_export">Export positive</button>

		<input id="inp_val_file_use" type="checkbox"><label for="inp_val_file_use"> Provide file download:</label>
		<input id="inp_val_file" value="text.txt">
	</div>

	
	<span id="span_export_count"></span>
	
	<div id="div_export">
		<b>Export</b><br />
		<textarea id="ta_validator_export"></textarea>
	</div>
	
	<!-- show only after successful upload -->
	<div id="div_validator_file">
		<hr>
		<a target="_blank" href="" id="a_validator_file" draggable="true" data-downloadurl=""></a>		
		<p>
		  <b><span id="span_validator_file"></span></b><br/>
		  Right-click to save file or drag to desktop (when using Chrome).<br/>
		  <br/>
		</p>
		{% if user %}
		<hr>
		<b>Create</b> new data model for file:<br/>
		<form action="/adm/new" method="POST">
			<input type="hidden" name="datafile" id="inp_validator_file" />
			Bucket:
			<input name="bucket" class="localstoragesave" id="inp_new_bucket" />
  			Caption*:
			<input name="caption" />
			<label for="inp_new_public">Public*</label> <input type="checkbox" id="inp_new_public" name="public" />
			<button>Create</button>
		</form>
		{% endif %}
	</div>	
	
	<div id="div_val_results">
		<hr>
		<table class="tbl_results">
		<tr>
		 <th>Test data</th>
		 <th style="width:100px;">Result</th>
		 <th style="width:100px;">Predicted</th>
		 <th style="width:10px;"></th>
		</tr>
		<tbody id="tb_val_results">
		</tbody>
		</table>
	</div>
	


<!--
  End
-->	
	
	</div>
	<div id="tabs-3">
	
<!--
  Generator
-->

	<p>Generate a learning file with data from a spread sheet</p>	
	
	<textarea id="ta_generator_in"></textarea>
	</span><b>Options</b></a><br />
	
	
<table>
<tr>
<td colspan="2">
	<input type="checkbox" id="inp_gen_firstcolnumber"><label for="inp_gen_firstcolnumber"> First column is a number value</label>
</td>
<td>
</tr>
<tr>	
<tr>
<td style="width:180px;"><input id="inp_gen_whitelist_use" type="checkbox"><label for="inp_gen_whitelist_use"> Whitelist characters:</label></td>
<td>
  <input id="inp_gen_whitelist" value="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz _0123456789">
</td>
</tr>
<tr>
<td><input id="inp_gen_min_words_use" type="checkbox"><label for="inp_gen_min_words_use"> Minimum words:</label></td>
<td>
  <input id="inp_gen_mim_words" value="3">
</td>
</tr>
<tr>
<td><input id="inp_gen_min_letters_use" type="checkbox"><label for="inp_gen_min_letters_use"> Minimum letters:</label></td>
<td>
  <input id="inp_gen_min_letters" value="20">
</td>
</tr>

<tr> 
<td><input id="inp_gen_whitewords_use" type="checkbox"><label for="inp_gen_whitewords_use"> Whitelist words:</label></td> 
<td> 
  Restrict word occurances. Minimum: <input id="inp_gen_whitewords_occur_min" value="2"> 
  Maximum: <input id="inp_gen_whitewords_occur_max" value="99999"> 
  <button id="btn_gen_whitewords_analyse" >Analyse input</button> 
  <br/> 
  <textarea id="ta_whitewords_out"></textarea> 
</td> 
</tr> 

<tr>
<td><input type="checkbox" id="inp_gen_lowercase"><label for="inp_gen_lowercase"> Convert to lower case</label></td>
<td>
  
</td>
</tr>
<tr>
<td><input id="inp_gen_file_use" type="checkbox"><label for="inp_gen_file_use"> Provide file download:</label></td>
<td>
  <input id="inp_gen_file" value="text.txt">
</td>
</tr>

</table>	

  
	
	<button id="btn_generator">Generate</button>
	<span id="span_gen_out_count"></span>
	<br />
	<div id="div_generator_out">
	  <b>Output</b><br />
	  <textarea id="ta_generator_out"></textarea>	
	  <button id="btn_load_learn">Load in Learn tab</button> Update existing model with this data
	</div>
	
	<!-- show only after successful upload -->
	<div id="div_generator_file">
		<a target="_blank" href="" id="a_generator_file" draggable="true" data-downloadurl=""></a>
		<p>
		  <b><span id="span_generator_file"></span></b><br/>
		  Right-click to save file or drag to desktop (when using Chrome).<br/>
		  <br/>
		</p>
		{% if user %}
		<hr>
		<b>Create</b> new data model for file:<br/>
		<form action="/adm/new" method="POST">
			<input type="hidden" name="datafile" id="inp_generator_file" />
			Bucket:
			<input name="bucket" id="inp_new_bucket" />
  			Caption*:
			<input name="caption" />
			<label for="inp_new_public">Public*</label> <input type="checkbox" id="inp_new_public" name="public" />
			<button>Create</button>
		</form>
		{% endif %}
	</div>

<!--
  End
-->	
	
	</div>
	<div id="tabs-4">
	
<!--
  About
-->
	<p>Prediction Wizard - A GUI for the <a href="http://code.google.com/apis/predict/">Google Prediction API</a></p>	

<table>
<tr>
  <td style="width:120px;">Directed by</td>
  <td>Federico Elles (<a href="http://www.twitter.com/illcom">@illcom</a>)</td>
</tr><tr> 
  <td>Based upon</td>
  <td>
   <a href="http://code.google.com/p/google-api-python-client/source/browse/samples/prediction/prediction.py">google-api-python-client</a> Sample Code</a> by
	Joe Gregorio
  </td>
</tr><tr> 
  <td>Inspired by</td>
  <td>Patrick Chanezon (<a href="http://www.twitter.com/chanezon">@chanezon</a>) at the Google Developer Day 2010 in Munich</td>
</tr><tr> 
  <td>GUI by</td>
  <td><a href="http://jqueryui.com/">jQuery UI</a></td>
</tr><tr> 
  <td>Hosted by</td>
  <td>The <a href="http://code.google.com/appengine/">Google App Engine</a></td>
</tr><tr> 
  <td>Graphics by<br/></td>
  <td>
    Icon by <a href="http://de.wikipedia.org/wiki/The_Legend_of_Zelda">Legend of Zelda</a> suggested by <a href="http://spritestrips.blogspot.com/">Ian DeMocca</a><br/>
    Text file icon by <a href="http://www.microsoft.com/windows/windows-7/">Windows 7</a> Default
  </td>
</tr><tr> 
  <td>Source code at</td>
  <td>
    <a href="http://code.google.com/p/predictionwiz/downloads/list">http://code.google.com/p/predictionwiz</a>
  </td>
</tr>



</table>


<!--
  End
-->	
	
	</div>
	
<div id="tabs-5">
	
<!--
  Mass Prediction
-->	
<p>Predict a large data set using an input file. Predictions will be provided as an output file</p>
<table>
<tr>
<td style="width:120px;">Model:</td>
<td>
  <select name="model" id="inp_model_mass">
  {% for record in records %}
	  <option value="{{record.key }}">{{ record.caption }}</option>
  {% endfor %}
  </select>
</td>
</tr>
<tr>
<td style="width:120px;">Caching:</td>
<td>Minutes: <input  type="number" id=inp_caching_mass value=0 /> 0 = No caching</td>
</tr>
<tr>
<td style="width:120px;">Delay:</td>
<td>Seconds: <input  type="number" id=inp_delay_mass value="0.3" /> 0 = No delay</td>
</tr>

<tr>
<td style="width:120px;">Auto LowerCase:</td>
<td><input id="inp_downcase_mass" type="checkbox"><label for="inp_downcase_mass">Input test will be lowercase</label></td>
</tr>
</table>	

	<p><b>Input</b></p>
	<textarea id="ta_mass_input" WRAP=OFF></textarea>
	<br /><button id="btn_mass_predict">Predict</button>
	<span id="span_mass_results_count"></span>
	<span id="span_mass_predicted_count"></span>
	<p><b>Output</b></p>
	<textarea id="ta_mass_output" WRAP=OFF></textarea>
	
	<div id="div_mass_export_block">
		<p><b>Export</b></p>
		Filename: <input id="inp_mass_file" value="text.txt"><button id="btn_mass_export">Export</button>

	
	
		<div id="div_mass_file">
			<a target="_blank" href="" id="a_mass_file" draggable="true" data-downloadurl=""></a>
			<p>
				<b><span id="span_mass_file"></span></b><br/>
				Right-click to save file or drag to desktop (when using Chrome).<br/>
				<br/>
			</p>
		</div>
	</div>	
<!--
  End
-->	
	
	</div>	
</div>

<p class="p_grey">
   It's a webapp, not a website. Created by Federico Elles, 2011-2012. <a href="http://code.google.com/p/predictionwiz/downloads/list">Download source code</a>
</p>

</body>


<script type="text/javascript">
//
// Enable Tabs
//
$(function() {
	$( "#tabs" ).tabs();
});


$('#div_result_log').hide();
$('#div_export').hide();
$('#div_generator_file').hide();
$('#div_validator_file').hide();
$('#div_mass_file').hide();

$('#div_generator_out').hide();
$('#div_val_more_options').hide();
$('#div_val_results').hide();
$('#div_mass_export_block').hide();

$('#div_result_log_learn').hide();
$('#tr_correction').hide()  

//
// save values for input files in localstorage
//
$(function() {
  $('select,input').each(function(index) {
  	sid = $(this).attr('id');
  	if (sid){
  	  val = localStorage.getItem("po_"+sid);
	  type = $(this).attr('type');
  	  if (val){
	    if (type == 'checkbox'){
		  if (val == 'true'){
		    $(this).attr('checked', true);
		  } else {
		    $(this).attr('checked', false);
		  }
		} else {
  	      $(this).val(val);
		}
  	  }
  	  //set onchange event for all
 	  $(this).change(function() {
  	    sid = $(this).attr('id');
		type = $(this).attr('type');
		val = $(this).val();
	    if (type == 'checkbox'){  
          val = $(this).attr('checked');
		} else {
		  val = $(this).val();
		}
        localStorage.setItem("po_"+sid,val);		
      });
    }
  });
});



//
// whitelist words generate click
//
$('#btn_gen_whitewords_analyse').click(function() {
	iMinOccur = $('#inp_gen_whitewords_occur_min').val();
	iMaxOccur = $('#inp_gen_whitewords_occur_max').val();
	//alert(iMaxOccur);
	try { iMinOccur = parseInt(iMinOccur);} catch (e){ iMinOccur = 1;$('#inp_gen_whitewords_occur_min').val('1');}
	try { iMaxOccur = parseInt(iMaxOccur);} catch (e){ iMaxOccur = 99999;$('#inp_gen_whitewords_occur_max').val('99999');}
	//alert('='+iMaxOccur);
	if (iMinOccur < 0){iMinOccur = 0;}	
	if (iMaxOccur < 0){iMaxOccur = 99999;}	
	whitelist = $('#inp_gen_whitelist').val();
	whitelist_use = $('#inp_gen_whitelist_use').attr('checked');
	lowercase = $('#inp_gen_lowercase').attr('checked'); //returns true or false
	sStr = $('#ta_generator_in').val();
	sStr = sStr.replace(/\t/g,' ')
	sStr = sStr.replace(/\n/g,' ')
	//lowercase
	if (lowercase){sStr = sStr.toLowerCase();}	
  
  //filter 
  if (whitelist !== '' && whitelist_use){
	  sStrOrig = sStr;
	  sStr = '';
    for(k=0;k<sStrOrig.length;k++){
	   cChar = sStrOrig.charAt(k);
	   if (whitelist.indexOf(cChar) >-1){
	     sStr += cChar;
	    }
    }
  }	
	
  while (sStr.indexOf('  ') > -1){
    sStr = sStr.replace(/  /g,' ');
	}	
	
	var asWords = sStr.split(" ");
	output = '';
	wordmap = new Array();
	for (i=0;i<asWords.length;i++){
		word = asWords[i];
		if (word !== ''){
		  if (wordmap[word] != undefined){
		  	wordmap[word] += 1;
	  	} else {
  			wordmap[word] = 1;
		  }
	  }
	}

  //generate output to text area
  
  var wordarray = new Array();
  for( var i in wordmap )
  {
    wordarray[wordarray.length] = [wordmap[i],i];
  }  

  wordarray.sort(function(a,b){return a[0] - b[0]});
  
  for (i=0;i<wordarray.length;i++) {
  	if (wordarray[i][0] >= iMinOccur && wordarray[i][0] <= iMaxOccur){ 
	    output += wordarray[i][1] + '\tx' + wordarray[i][0] + '\n';
	  }
  }
  
  
  //old output, unsorted
  /*
  for (var i in wordmap) {
  	if (wordmap[i] >= iMinOccur && wordmap[i] <= iMaxOccur){ 
	    output += i + '\tx' + wordmap[i] + '\n';

	  }
  }
  */
	
	$('#ta_whitewords_out').val(output);
	
}); 

//
// generator click
//
$('#btn_generator').click(function() {
  $('#div_generator_file').hide();
  //read options
  whitelist = $('#inp_gen_whitelist').val();
  min_words = $('#inp_gen_mim_words').val();
  try { min_words = parseInt('0'+min_words)-1;} catch (e){ min_words = 1;$('#inp_gen_mim_words').val('1');}
  if (min_words < 0){min_words = 0;}
  min_letters = $('#inp_gen_min_letters').val();
  try { min_letters = parseInt('0'+min_letters);} catch (e){ min_letters = 1; $('#inp_gen_min_letters').val('1')}
  lowercase = $('#inp_gen_lowercase').attr('checked'); //returns true or false
  whitelist_use = $('#inp_gen_whitelist_use').attr('checked');
  min_words_use = $('#inp_gen_min_words_use').attr('checked');
  min_letters_use = $('#inp_gen_min_letters_use').attr('checked');
  whitewords_use = $('#inp_gen_whitewords_use').attr('checked');
  firstcolnumber_use = $('#inp_gen_firstcolnumber').attr('checked');
  
  file_use = $('#inp_gen_file_use').attr('checked');
	if (whitewords_use){  
    // gen whitelist
		wordmap = new Array();
		asWords = $('#ta_whitewords_out').val().split('\n');
		
		for (i=0;i<asWords.length;i++){

			asWordparts = asWords[i].split('\t');
  		wordmap[asWordparts[0]] = 1;
		}
	}
  
  //process
  input = $('#ta_generator_in').val();
  $('#ta_generator_out').val('');
  html = '';
  count=0;
  //processing
  asRow = input.split("\n");
  for (i=0;i<asRow.length;i++){
    if (asRow[i] !== ""){
      asCol = asRow[i].split("\t");
      if (asCol.length > 1){
	  if (jQuery.trim(asCol[0]) !== '' && (jQuery.trim(asCol[1]) !== '' || asCol.length > 2)){
	    bAdd = true;
		htmlrow = '';
	    for (j=0;j<asCol.length;j++){
		  sStr = jQuery.trim(asCol[j]);
		  //kill double space
		  while (sStr.indexOf('  ') > -1){
		    sStr = sStr.replace(/  /g,' ');
		  }
		  // kill "
		  sStr = sStr.replace(/"/g,'');
		  //lowercase
		  if (lowercase){sStr = sStr.toLowerCase();}
		  //filter 
          if (whitelist !== '' && whitelist_use){
		    sStrOrig = sStr;
			sStr = '';
		    for(k=0;k<sStrOrig.length;k++){
			  cChar = sStrOrig.charAt(k);
			  if (whitelist.indexOf(cChar) >-1){
			    sStr += cChar;
			  }
			}
		  }
		  
		  // whitelist words
		  //
		  if ($('#ta_whitewords_out').val() !== '' && whitewords_use && j > 0){
		  	asWords = sStr.split(' ');
		  	for (k=0;k<asWords.length;k++){
		  		word = asWords[k];
		  		if (wordmap[word] == undefined){
		  			sStr = sStr.replace(word,'');
		  		}
		  	}
		  	
		    //kill double space
		    while (sStr.indexOf('  ') > -1){
				sStr = sStr.replace(/  /g,' ');
			}		  	
		  }
		  
		  //minimum characters - not for result column
		  if (min_letters > 0 && j > 0 && min_words_use){
		    if (sStr.length < min_letters){ bAdd = false;}
		  }
		  //minimum words
		  if (min_words > 0 && j > 0 && min_words_use){
		    iSpaces =  sStr.length - sStr.replace(/ /gi,'').length;
			if (iSpaces < min_words){ bAdd = false;}
		  }
		  
		  //finalize
		  if (!(firstcolnumber_use && j == 0)){
		    sStr= '"'+sStr+'"';
		  }
		  if (j != asCol.length-1){ sStr += ', '; } // add comma
  	      htmlrow += sStr;
		}
		if (bAdd){
		  html += htmlrow;
		  if (i != asRow.length-1){ html += '\n'; } // add comma
		  count++;
		}
	  }
	  }
    }
  }
  //output
  $('#div_generator_out').show();  
  $('#ta_generator_out').val(html);
  $('#span_gen_out_count').html(count + ' records generated');
  if (file_use && count > 0){
	/*$.ajax({url: "/text",
  	  data: {text: html}, 
	  type: 'POST',
      success: function(data){
        filename = $('#inp_gen_file').val();
	    dlpath = data;
	    dlurl = 'text/plain; charset=UTF-8:'+filename+':'+dlpath;
	    $('#a_generator_file').attr('data-downloadurl',dlurl);
		$('#a_generator_file').attr('href',data);
	    $('#inp_generator_file').val(filename);
	    $('#span_generator_file').html(filename);
	    $('#div_generator_file').show();
	    
	  },
	  error: function(xhr, settings, exception) {
	    help_error(xhr, settings, exception);
      }
	});*/
	provideDownload('#inp_gen_file','generator', html);
  }
  
});

function provideDownload(input_field, context_name, filecontent ){
  $.ajax({url: "/text",
  	  data: {text: filecontent}, 
	  type: 'POST',
      success: function(data){
        filename = $(input_field).val();
	    dlpath = data;
	    dlurl = 'text/plain; charset=UTF-8:'+filename+':'+dlpath;
	    $('#a_'+context_name+'_file').attr('data-downloadurl',dlurl);
		$('#a_'+context_name+'_file').attr('href',data);
	    $('#inp_'+context_name+'_file').val(filename);
	    $('#span_'+context_name+'_file').html(filename);
	    $('#div_'+context_name+'_file').show();
	    
	  },
	  error: function(xhr, settings, exception) {
	    help_error(xhr, settings, exception);
      }
  });
}




//
// generator download result file
// via http://www.thecssninja.com/javascript/gmail-dragout
//
var file2 = document.getElementById("a_generator_file");

file2.addEventListener("dragstart",function(evt){
    evt.dataTransfer.setData("DownloadURL",file2.getAttribute("data-downloadurl"));
},false);


// --------- //
// VALIDATOR //
// --------- //

//
// validator download result file
//
var file = document.getElementById("a_validator_file");

file.addEventListener("dragstart",function(evt){
    evt.dataTransfer.setData("DownloadURL",file.getAttribute("data-downloadurl"));
},false);


//
//needed for sorting multi ouput result
//
function outputSort(a,b){
  return b.score - a.score;
}

function outputSortLabel(a,b){
  return b.label - a.label;
}

//
// Validator invoke
//
$('#a_validator').click(function() {
  $('#div_validator').show();  
  $('#a_validator').hide();
});

//
// show failed rows
//
$('#btn_show_failed').click(function() {
  $('.val_train_row').each(function(index) {
	$(this).show();
    if (!$(this).hasClass('predict_failed')){
		$(this).hide();
	} 
  });
});

//
// show all rows
//
$('#btn_show_all').click(function() {
  $('.val_train_row').each(function(index) {
	$(this).show();
  });
});


//
// export successful rows
//
$('#btn_export').click(function() {
  $('#btn_export').attr('disabled','disabled');
  html = '';
  j=0;
  $('.val_train_row').each(function(index) {
	$(this).show();
    if ($(this).hasClass('predict_failed')){
		$(this).hide();
	} else {
		rowid = $(this).attr('rowid')
		html += '"' + $('#result'+rowid).html() + '", "' + 
		        jQuery.trim($('#testdata'+rowid).html()) + '"' + 
				String.fromCharCode(10);
		j++;
	}
  });
  $('#div_export').show();
  $('#ta_validator_export').val(html);
  $('#span_export_count').html(j + ' records exported');
  $('#btn_export').attr('disabled','');
  
  file_use = $('#inp_val_file_use').attr('checked');
  if (j>0 && file_use){
	$('#div_validator_file').hide();
    provideDownload('#inp_val_file','validator',html)
  }
});



//
// reload one record
//
function reloadRecord(i){
  $('#td_result'+i).removeClass('span_wrong');
  $('#td_result'+i).removeClass('span_correct');
  predictRecord($('#inp_model_val').val(), $('#result'+i).html(),$('#testdata'+i).html(),i);
}

//
// validator one record
//
function predictRecord(model, result, testdata, i){
  $('#td_result'+i).html("Working...");
  $.ajax({url: '/api/predict',
	type: 'POST',
	data: {model:model,content:testdata,addreturn:'||'+i+'||'+result},
	success: function(data) {
	
	  asReturn = data.split('||');
	  if (asReturn.length == 3){
		
		sPredicted = asReturn[0];
		sID = asReturn[1];
		sResult = asReturn[2];
	  
		res_style = 'span_wrong';
		$('#row'+sID).removeClass('predict_failed');
		if (sPredicted == sResult){
			res_style = 'span_correct';
		} else {
		  $('#row'+sID).addClass('predict_failed');
		}
		$('#td_result'+sID).html(sPredicted);
		$('#td_result'+sID).addClass(res_style);
		//feed counter
		gpredictcounter++;
		$('#span_val_predicted_count').html('- '+gpredictcounter+ ' records predicted');
		
	  } else {
		$('#td_result'+sID).html(asReturn);
	  }			  
	},
	error: function(XMLHttpRequest, textStatus, errorThrown) {
	  $('#td_result'+sID).html(textStatus);
	}	
  });
}


//
// validator button click
//
var gpredictcounter = 0;
$('#btn_validator').click(function() {
    $('#tb_val_results').empty();
	$('#btn_validator').attr('disabled','disabled');
	
	
	sImport = $('#ta_validator').val();
    asRow = sImport.split("\n");
	j=0;
	gpredictcounter=0;
	model = $('#inp_model_val').val();
    for (i=0;i<asRow.length;i++){
		
		asRecord = asRow[i].split(',');
		if (asRecord.length > 1){
		  sResult = asRecord[0].replace(/"/g,"");
		  asRecord.shift();
		  sTestData = asRecord.join(',');
		  //sTestData = asRecord[1].replace(/"/g,"");
		  $('#tb_val_results').append('<tr rowid="'+i+'" class="val_train_row" id="row'+i+'">'+
			'<td id="testdata'+i+'">'+sTestData+'</td>'+
			'<td id="result'+i+'">'+sResult+'</td>'+
			'<td id="td_result'+i+'"></td>'+
			'<td><button title="Repredict record" onClick="reloadRecord('+i+');">R</button></td>'+
			'</tr>');
		  j++;
		  //submit request
		  setTimeout("predictRecord('"+model+"','"+ sResult+"','"+ sTestData+"','"+ i+"');",1000*i);
		  //setTimeout(function(){
		  //  predictRecord(model,sResult,sTestData+,i)
		  //},1000*i);
		  //predictRecord(model, sResult, sTestData, i);
		  //end submit request
		}
	}
    $('#span_val_results_count').html(j + ' records loaded ');
	$('#div_val_results').show();
	$('#div_val_more_options').show();
	//$('#c').show();
	$('#btn_validator').attr('disabled','');
});

//
// validator drop file handle
//

var holder = document.getElementById('ta_validator');
holder.ondragover = function () { this.className = 'ta_file_hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondragleave = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
  this.className = '';
  e.preventDefault();

  var file = e.dataTransfer.files[0],
      reader = new FileReader();
  reader.onload = function (event) {
   $('#ta_validator').val(event.target.result); 
  };
  reader.readAsText(file);

  return false;
};


// --------- //
// Simulator //
// --------- //

$('#inp_model').change(function(){
  try{
  $('.span_sim_model_key').html($(this).val());
  $('#a_demo').attr('href','/demo/'+$(this).val()+'/'+$('#inp_model option:selected').html())
  } catch(e){}
});
$('#inp_model').change()
//
// Predict button handler
//
$('#form_gen').submit(function() {
  $('#div_result').html("Working...");
  $('#span_correct_result').html('')
  $.ajax({url: '/api/predict',
    dataType: $('#datatype').val(),
	type: 'POST',
    data: $('form').serialize(),
	success: function(data) {
	  data_debug = data;
	  $('#tr_correction').hide()  
	  if ($('#datatype').val() == 'json'){
	    html = '<b>';
		if (data.outputLabel) 
			{html+=data.outputLabel;} 
		else 
			{html+=(Math.round(data.outputValue*100)/100).toString();}
		
		html +='</b>';
		j=0;
		
		try {
			if (data.outputMulti){
			    $('#tr_correction').show()
				var $sel = $('#sel_answer')
				var $quick = $('#div_quick_answer')
				var $quickButtons = $('#div_quick_buttons')
				$quickButtons.html('')
				var bQuick = false
				$quick.hide()
				$sel.html('<option></option>')
				if (data.outputMulti.length < 11){
					$quick.show()
					bQuick = true
				}
				for (i=0;i<data.outputMulti.length;i++){
					$sel.append('<option value="'+data.outputMulti[i].label+'">'+data.outputMulti[i].label+'</option>')
					if (bQuick){
					  $quickButtons.append('<button class=btn_quick_correction value="'+data.outputMulti[i].label+'">'+data.outputMulti[i].label+'</button>')
					}
				}
				
				if (bQuick){	
					// Prediction Correction
					$('.btn_quick_correction').click(function(event){
					  event.preventDefault();
					  var val = $(this).attr('value')
					  $('#sel_answer').val(val)
					  $('#btn_correct').click()
					})
				}	
				
				aSort = data.outputMulti.sort(outputSort);
		
				//show only second and third best reults
				for (i=0;i<aSort.length;i++){
				if  (j < 3 && j > 0){
					html += ' <span class="span_pos'+j+'">['+aSort[i].label+']</span>';
				}
				j++;
			}
		  }
		} catch (e){
		  html = data;
		}

	  } else {
	    html = data;
	  }
  
      $('#div_result').html(html);
  
      //write log
	  $('#div_result_log').show();
      $('#tb_result_log').prepend('<tr"><td>' + $('#inp_content').val() + '</td><td>' +  $('#div_result').html() + '</td></tr>');

	  // update API
	  $('.span_sim_model_key').html($('#inp_model').val());
	  
      
    },
	error: function(XMLHttpRequest, textStatus, errorThrown) {
      $('#div_result').html(textStatus);
    }	
  });
  return false;
});



$('#btn_correct').click(function(event){
  event.preventDefault();
  $('#span_correct_result').html('Working...');
  var data = {}
  data.model = $('#inp_model').val()
  data.answer = $('#sel_answer').val()
  data.content = $('#inp_content').val()
  $(this).attr('disabled',true)
  $.ajax({url: '/api/learn',
	type: 'GET',
    data: data,
	success: function(data) {
	  data_debug = data;
	  if (data == 'prediction#training') data = "Submitted"
      $('#span_correct_result').html(data);
  	  $('#btn_correct').attr('disabled',false)
      
    },
	error: function(XMLHttpRequest, textStatus, errorThrown) {
      $('#span_correct_result').html(textStatus);
	  $('#btn_correct').attr('disabled',false)
    }	
  });  
})

// ----- //
// Learn //
// ----- //

//
// Predict button handler
//
var aRecs
var iRec = 0
var iRecMax = 0
$('#form_learn').submit(function() {
  $('#div_result_learn').html("Working...");
  aRecs = $('#inp_content_learn').val().split('\n')
  iRecMax = 0
  iRec = 0
  for (i=0;i<aRecs.length;i++){  
	  var data = {}
	  data.model = $('#inp_model_learn').val()
	  var a = aRecs[i].split(',')
	  if (a.length < 2){
		$('#div_result_learn').html("Learning data must have at least two values seperated by comma");
		aRecs.splice(i,1) 
		i--
	  } else {
	      iRecMax++
		  data.answer = a.shift()
		  data.content = a.join(',')
		  $.ajax({url: '/api/learn',
			type: 'GET',
			data: data,
			success: function(data) {
			  data_debug = data;

			  $('#div_result_learn').html(data);
		  
			  //write log
			  $('#div_result_log_learn:hidden').show();
			  $('#tb_result_log_learn').prepend('<tr"><td>' + aRecs[iRec] + '</td><td>' +  data + '</td></tr>');
			  iRec++
			  
			  if (iRecMax == iRec) $('#div_result_learn').html('Done.')
			  
			},
			error: function(XMLHttpRequest, textStatus, errorThrown) {
			  $('#div_result_learn').html(textStatus);
			   //write log
			  $('#div_result_log_learn:hidden').show();
			  $('#tb_result_log_learn').prepend('<tr"><td>' + aRecs[iRec] + '</td><td>' +  textStatus + '</td></tr>');
			  iRec++
			}	
		  });
	  }
  }  
  // update API
  $('.span_sim_model_key').html($('#inp_model').val());
  return false;
});

// FILL LEARN INPUT WITH GENERATOR OUTPUT
$('#btn_load_learn').click(function(){
  $('#inp_content_learn').val($('#ta_generator_out').val())
  $("#tabs").tabs('select',4);
})


// --------------- //
// MASS PREDICTION //
// --------------- //

//
// mass prediction drop file handle
//
var gfile;
var holder = document.getElementById('ta_mass_input');
holder.ondragover = function () { this.className = 'ta_file_hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondragleave = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
  this.className = '';
  e.preventDefault();

  var file = e.dataTransfer.files[0], reader = new FileReader();
  reader.onload = function (event) {
    $('#ta_mass_input').val(event.target.result); 
  };
  reader.readAsText(file);
  gfile = file;
  file_name = file.name;
  //add predicted suffix
  if ((pointpos = file_name.indexOf('.'))> -1){
    file_name = file_name.substr(0,pointpos)+'.predicted.'+file_name.substr(pointpos+1);
  }
  $('#inp_mass_file').val(file_name); 

  return false;
};


//
// mass prediction button click
//
var gmasspredictcounter = 0;
var gmasspredictcounter_init = 0;
var delay = 0;
var ga_mass;
var code;
$('#btn_mass_predict').click(function() {
    //$('#tb_val_results').empty();
	$('#btn_mass_predict').attr('disabled','disabled');
	$('#div_mass_export_block').hide();
	$('#ta_mass_output').val(''); //empty output
	caching = $('#inp_caching_mass').val()
	delay = $('#inp_delay_mass').val()
	delay = parseFloat(delay)
	if (isNaN(delay)) delay = 0.5;
	console.log('delay:',delay);
	
	downcase = $('#inp_downcase_mass').attr('checked')
	ga_mass = {};
	
	sImport = $('#ta_mass_input').val();
    asRow = sImport.split("\n");
	j=0;
	gmasspredictcounter=0;
	model = $('#inp_model_mass').val();
    for (i=0;i<asRow.length;i++){
		//each row is already input data:
		ga_mass[i+'']={
		  'rec':i,
		  'data':asRow[i],
		  'result':''
		};
		rowvalue = asRow[i].replace(/'/g,"\\'")
		if (downcase) rowvalue = rowvalue.toLowerCase()
		code = "predictMassRecord('"+model+"','"+rowvalue+"',"+i+","+caching+");";
		setTimeout(code,delay*1000*i);
		j++;
	}
	
    $('#span_mass_results_count').html(j + ' records loaded ');
	gmasspredictcounter_init = j;
	//$('#div_mass_results').show();
	//$('#div_mass_more_options').show();
	//$('#c').show();
	$('#btn_mass_predict').attr('disabled','');
});


//
// mass prediction one record
//
function predictMassRecord(model, testdata, i, caching){
  if (typeof caching == "undefined") caching = 0
  //$('#td_result'+i).html("Working...");
  $.ajax({url: '/api/predict',
	type: 'POST',
	data: {model:model,content:testdata,addjson:'||'+i+'||'+testdata,caching:caching},
	success: function(data) {
	  gmasspredictcounter++;

	  asReturn = data.split('||');
	  txt = $('#ta_mass_output').val();
	  if (asReturn.length == 3){
		
		
		sID = asReturn[1];
		sTestData = asReturn[2];
		data = jQuery.parseJSON(asReturn[0]);
		data_debug = data;
		sPredicted = asReturn[0];
		
		
		if (data.outputLabel) 
			{sPredicted=data.outputLabel;} 
		else 
			{sPredicted=(Math.round(data.outputValue*100)/100).toString();}
			
		
		sMultiResults = '';
		pretxt = '';
		if (data.outputMulti){
		  aSort = data.outputMulti.sort(outputSortLabel);
		
		  //print header if record 0
		  if (sID=="0"){
		    pretxt = 'Result,';
		    for (i=0;i<aSort.length;i++){
		      pretxt += aSort[i].label +',';
		    }
		    pretxt += 'Testdata\n';
		  } 
		  
		  for (i=0;i<aSort.length;i++){
		    sMultiResults += aSort[i].score +',';
		  }
		  
		  ga_mass[sID].multi = aSort; //save multi in global object

		}
		
		
		
		//add " if not a number
		if (isNaN(parseInt(sPredicted))){
		  sPredicted = '"'+sPredicted+'"';
		}
		ga_mass[sID].result = sPredicted;
	    $('#ta_mass_output').val(txt+pretxt+sPredicted+','+sMultiResults+sTestData+'\n');

		//feed counter
		$('#span_mass_predicted_count').html('- '+gmasspredictcounter+ ' records predicted');
	
		
		
	  } else {
		 $('#ta_mass_output').val('ERROR: Can not understand feedback\n');
		 console.log('Mass Prediction ERROR:',txt,asReturn)
	  }			
	  if (gmasspredictcounter_init == gmasspredictcounter){
		$('#div_mass_export_block').show();
	  }	  
	},
	error: function(XMLHttpRequest, textStatus, errorThrown) {
	  txt = $('#ta_mass_output').val();
  	  gmasspredictcounter++;
	  $('#ta_mass_output').val(txt+'ERROR:'+textStatus+'\n');
	}	
  });
}

$('#btn_mass_export').click(function(){
  html = 'Result,';

  l = 0;
  for (x in ga_mass){
    rec = ga_mass[x];
    rec_multi = '';
    if (typeof rec.multi !== 'undefined'){
      if (l==0){
	    for (i=0,ii=rec.multi.length;i<ii;i++){
	      html += rec.multi[i].label +',';
	    }
	    html += 'Inputdata\n';
	    l = 1;
	  }
	  //loop scores
	  for (i=0,ii=rec.multi.length;i<ii;i++){
	    rec_multi += rec.multi[i].score +',';
	  }
	}
	html += rec.result+','+rec_multi+rec.data+'\n';
  }
  provideDownload('#inp_mass_file','mass', html);
});


//
// generator download result file
// via http://www.thecssninja.com/javascript/gmail-dragout
//
var file3 = document.getElementById("a_mass_file");

file3.addEventListener("dragstart",function(evt){
    evt.dataTransfer.setData("DownloadURL",file3.getAttribute("data-downloadurl"));
},false);

// ----- //
// OTHER //
// ----- //


//
// Text area hints
//

 function ta_hint(id, text){
   $('#'+id).val(text);
   $('#'+id).focus(function(e) {
     if($('#'+id).val() == text) {
      $('#'+id).val("");
     }
   });
 
    $('#'+id).blur(function(e) {
     if($('#'+id).val() == "") {
       $('#'+id).val(text);
     }
   });
 }

 ta_hint('ta_generator_in', 'Select cells to use, copy and paste here.');
 ta_hint('ta_validator', 'Paste file content here (or drop file when using Chrome).');
 ta_hint('ta_mass_input', 'Paste file content here (or drop file when using Chrome).');

//
// H1 Link
//
$('h1').click(function(){
  location.href='/';
});
 
//
// Show AJAX Error
//
function help_error(xhr, settings, exception){
  alert('error in: ' + xhr.statusText + ' \\n'+'response:\\n' + xhr.responseText.substr(1,1000) + ' \\n'+'uri:\\n' + settings.uri);
}

</script>

</html>